perm filename TCPUSR.MAC[IP,SYS] blob
sn#680232 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-TCP>TCPUSR.MAC.40303 6-May-82 16:00:56, Edit by CLYNN
; Return IP/TCP options to user; Return error msg in TVTOPN failure
;<403-TCP>TCPUSR.MAC.40301 29-Jan-82 15:08:41, Edit by CLYNN
; Updated for TCP release 3
;[BBNF]<401-TCP>TCPUSR.MAC.78, 24-Jul-81 11:45:00, Ed: CLYNN
; Fix: Return error code even if abort in progress in USRBF*,
; No room return for USRINI
;SNARK:<401-TCP>TCPUSR.MAC.77 26-Mar-81 15:57:30, Edit by CLYNN
; USRBFE & USRBFF: Switch calls to BFRDUN and USTTUM so BFRDUN doesn't
; DISMS while NOSKED
; USRABD: Don't let abort counter underflow
SEARCH INPAR,TCPPAR,PROLOG
TTITLE TCPUSR
SUBTTL TCP User Responses from TCP, William W. Plummer, 21MAR77
SWAPCD
COMMENT !
Routines in this file are called from within the TCP to
inform the user of various events that have occurred such as
a connection opening or closing, or a buffer completion.
* USREVT ... 3 ...... User Event (Open/close)
* USRERR ... 7 ...... User Error condition (ReXmit timeout etc)
* USRURG ... 7 ...... Urgent data has arrived
* USRBFE ... 8 ...... User Buffer Empty
* USRBFF ... 9 ...... User Buffer Full
* USRABD ... 10 ...... User ABORT Done
BFRDUN ... 10 ...... Handle completed buffer
* USRINI ... 11 ...... Initialize the user interface
!
; USREVT(EVENT, TCB) Connection open or close
;T1/ Event Code (Error Code) (377B35)
;TCB/ (Extended) Locked Connection block
; CALL USREVT
;Ret+1: Always
USREVT::LOCAL <CODE>
MOVEM T1,CODE
JN TSABT,(TCB),USREVX ; Ignore if ABORT in progress
LOAD T1,TOPNF,(TCB) ; Index of open/close wait bit index
LOAD T2,TSSYN,(TCB) ; Send state
LOAD T3,TRSYN,(TCB) ; Recv state
CAIN T2,NOTSYN ; Both NOT SYNCHRONIZED?
CAIE T3,NOTSYN
JRST USREV1
; State now NOT-NOT
CALL CLRWTB ; Yes. Clear the wait bit (now CLOSED)
JRST USREV2 ; Cannot be SYN-SYN too
USREV1:
; LOAD T2,TSSYN,(TCB) ; Get States again
; LOAD T3,TRSYN,(TCB)
CAIN T2,SYNCED ; Both fully synchronized?
CAIE T3,SYNCED
JRST USREV2 ; No
; State now SYN-SYN
JN TSOPN,(TCB),USREVX ; Jump if we have already said its open
SETONE TSOPN,(TCB) ; Indicate that is now true
; LOAD T1,TOPNF,(TCB)
CALL SETWTB ; Set the wait bit.
REPEAT 0,<
CALL GETRBS ; Get buffer size (e.g. packet size)
SKIPG T1 ; Present
> ; End of REPEAT 0
SETZ T1, ; Not present
CALL TCPMXP ; Set buffer size (TSMXP)
USREV2:
; Any state
JN TTVT,(TCB),USREV3 ; Jump if a virtual terminal
; Here for non-TVT actions
LOAD T1,TPICX,(TCB) ; Get Status-Change channel
LOAD T2,TPIFX,(TCB) ; And FORKX to PSI
CAIE T1,77 ; No channel named
CAIN T2,-1 ; or fork went away,
EXIT USREVX ; Means no PSI
CALL PSIRQ ; Set off the PSI
JRST USREVX
; Here for TVT actions
USREV3: CAIN CODE,OK ; What kind of event is this?
JRST USREV4 ; Must be open
MOVE T1,CODE ; Must be something to do with closing
CALL TVTCLS ; Go close the Virtual terminal
JRST USREVX
USREV4: CALL TVTOPN ; Open a TCP Virtual Terminal
JUMPE T1,USREVX ; Done if TVT assigned
MOVEM T1,CODE ; Save error code (ELT+↑D4)
; Failed to assign a TVT to the connection. The connection is now
; synchronized in both directions. Try to send an error message to
; the other end before we abort the connection so the user has some
; idea of why the connection is being aborted.
PUSH P,PKT ; Save these
PUSH P,TPKT
MOVX T1,4*<TVTFUE-TVTFUL> ; Message length, words
SETZ T2, ; Have a TCB
CALL TCPIPK ; Get empty packet
JRST USREV7 ; Failed, just abort connection
LOAD T1,PIPL,(PKT) ; Update packet byte length
ADDI T1,4*<TVTFUE-TVTFUL>
STOR T1,PIPL,(PKT)
MOVX T1,<TVTFUE-TVTFUL> ; Move message into packet
XMOVEI T2,TVTFUL
LOAD T3,PTDO,(TPKT)
ADD T3,TPKT
CALL XBLTA
SETONE <PEOL,PFIN>,(TPKT) ; This is the last data
LOAD T1,TSSEQ,(TCB) ; Set the sequence #
STOR T1,PSEQ,(TPKT)
ADDI T1,4*<TVTFUE-TVTFUL>+1 ; End seq # is initial + data + FIN
MODSEQ T1
STOR T1,TSSEQ,(TCB) ; Advance Send sequence
STOR T1,PESEQ,(PKT) ; Save recomputed end of packet
SETZRO PPROG,(PKT) ; Don't bother with retransmissions
; CALL SETRXP ; Setup packet rexmit parameters
MOVE T1,TODCLK ; Current millisecond
STOR T1,PTG,(PKT) ; Packet Time Generated
REPEAT 0,<
SKIPN INTSCR ; In secure mode?
JRST ; No. Avoid the overhead.
JE PPROG,(PKT), ; See if pkt will be ACK'd
LOAD T2,TSLVN,(TCB) ; Guaranteed that KDC will here the word
STOR T3,TSLVC,(TCB) ; So update the current level
: > ; End of REPEAT 0
SETO T1, ; No TVT line block
CALL EMTPKT ; Send the packet
AOS FINSCT
; Now send a RESET to get connection closed
SETZB T1,T2 ; Have a TCB & no data
CALL TCPIPK ; Get empty packet
JRST USREV7 ; Give up if no space
LOAD T1,TSSEQ,(TCB) ; Set the sequence #
STOR T1,PSEQ,(TPKT)
STOR T1,PESEQ,(PKT) ; Save recomputed end of packet
SETONE <PRST>,(TPKT) ; Don't reply
SETZRO PPROG,(PKT) ; Don't bother with retransmissions
; CALL SETRXP ; Setup packet rexmit parameters
MOVE T1,TODCLK ; Current millisecond
STOR T1,PTG,(PKT) ; Packet Time Generated
REPEAT 0,<
SKIPN INTSCR ; In secure mode?
JRST ; No. Avoid the overhead.
JE PPROG,(PKT), ; See if pkt will be ACK'd
LOAD T2,TSLVN,(TCB) ; Guaranteed that KDC will here the word
STOR T3,TSLVC,(TCB) ; So update the current level
: > ; End of REPEAT 0
SETO T1, ; No TVT line block
CALL EMTPKT ; Send the packet
AOS RSTSCT
; Following is done by TVTCLS
; SETZRO TSUOP,(TCB) ; Fake a CLOSE
; LOAD T1,TJCN,(TCB) ; Release the JCN
; CALL RETJCN
USREV7:
POP P,TPKT ; Restore registers
POP P,PKT
MOVE T1,CODE ; Error code
CALL ABTCON ; Abort the connection (ABTCON/USREVT/TVTCLS)
USREVX: RESTORE
RET
TVTFUL: BYTE (8)"4","2","1"," ","N","o"," ","f","r","e","e"," "
BYTE (8)"t","e","r","m","i","n","a","l","s",15,12
TVTFUE:
; USRERR(Code) Indicate TCP error condition to user
; May be called for TVTs with either error
;T1/ TCP-style error code
; EFP+↑D7 RST Received
; ELP+↑D9 RX timeout
;TCB/ (Extended) Locked Connection block
;
; CALL USRERR
;Ret+1: Always
USRERR::NOSKED
STOR T1,TERR,(TCB) ; Save the event code for user to see
JN TSABT,(TCB),USRER1 ; Forget PSI if ABORT in progress
LOAD T1,TPICE,(TCB) ; Get the error channel
LOAD T2,TPIFE,(TCB) ; Get the error FORKX
CAIE T1,77 ; No channel named
CAIN T2,-1 ; or fork went away
CAIA ; Skip the PSI
CALL PSIRQ ; Poke that fork's channel
USRER1:
LOAD T1,TERRF,(TCB) ; Index of the error flag
CALL SETWTB ; Set it to wake up waiting process(es)
OKSKED
RET
; USRURG(TCB) Alert user that Urgent data is to be read
;TCB/ (Extended) Locked Connection Block
;
; CALL USRURG
;Ret+1: Always.
USRURG::JN TSABT,(TCB),USRURX ; Forget if ABORT in progress
LOAD T1,TPICU,(TCB) ; Get the URG channel
LOAD T2,TPIFU,(TCB) ; and FORKX
CAIE T1,77 ; None named
CAIN T2,-1 ; or fork went away
EXIT USRURX ; Skip the PSI
CALL PSIRQ ; Request the PSI in that fork
USRURX: RET
; USRBFE(BFR) User buffer empty condition (SEND, etc)
; Never called for TVTs
;T1/ TCP-style event code and flags
;TCB/ (Extended) Locked Connection Block
;BFR/ (Extended) Buffer descriptor
;
; CALL USRBFE
;Ret+1: Always
USRBFE::PUSH P,T1 ; Save the code for a second
CALL SETTUM ; Make map user into our user space (NOSKED)
POP P,T1 ; Recover the code
JE TSABT,(TCB),USRBE2 ; Different error if ABORT in progress
MOVX T1,<<ELP+↑D14>B7> ; Connection reset
USRBE2:
LOAD T2,BHADR,(BFR) ; Origin of the Buffer Header
LOAD T3,BCNT,(BFR) ; Get the count
UMOVEM T3,BFRCNT(T2) ; Store into user space
JUMPE T3,USRBE3 ; Skip if whole buffer sent
LOAD T4,TSBYT,(TCB) ; Reduce outstanding count
SUB T4,T3 ; by bytes not sent
STOR T4,TSBYT,(TCB)
USRBE3:
TXO T1,TCP%DN ; Buffer done bit
MOVX T3,<-1B7+TCP%DN> ; Bits changed here
AND T1,T3 ; Flush stray bits
XCTU [ANDCAM T3,BFRFLG(T2)] ; Clear in user space
XCTU [IORM T1,BFRFLG(T2)] ; Set to tell the user it has finished
CALL USTTUM ; Unmap the user space & OKSKED
LOAD T1,TPICS,(TCB) ; Get the SEND done PSI Channel
LOAD T2,TPIFS,(TCB) ; And forkx
CALLRET BFRDUN ; Dispose of the buffer
; USRBFF(FLAGS,BFR) User buffer filled (RECV)
; Never called for TVTs
;T1/ TCP-style event code and flags (TCP%PU, TCP%UR, etc.)
;BFR/ (Extended) Buffer desciptor which is completing
;TCB/ (Extended) Locked Connection Block
;
; CALL USRBFF
;Ret+1: Always.
USRBFF::PUSH P,T1 ; Save the code
CALL SETTUM ; Map the user into our user space (NOSKED)
POP P,T1 ; Recover the code
JE TRURG,(TCB),USRBFA ; Jump if not in receive urgent mode
TXO T1,TCP%UR ; Give urgent flag in buffer
USRBFA:
JE TSABT,(TCB),USRBF2 ; Different error if ABORT in progress
MOVX T1,<<ELP+↑D14>B7> ; Connection reset
USRBF2:
LOAD T2,BHADR,(BFR) ; Get address of header in user space
LOAD T3,BCNT,(BFR) ; Get count from monitor copy of header
UMOVEM T3,BFRCNT(T2) ; Store into user copy
LOAD T4,TRBS,(TCB) ; Amount of RECV buffer space
SUB T4,T3 ; The whole buffer is going back!
; Shrinking the window is bad!!
STOR T4,TRBS,(TCB) ; Leave what is left for window setting.
TXO T1,TCP%DN ; Set the done bit
MOVX T3,<-1B7+TCP%PU+TCP%UR+TCP%DN> ; Bit we change
AND T1,T3 ; Flush stray bits
XCTU [ANDCAM T3,BFRFLG(T2)] ; Clear in user space
XCTU [IORM T1,BFRFLG(T2)] ; Merge with user's header
MOVX T1,<.RTJST(-1,PIDO)-<MINIHS+3>/4> ; Max IP option words
XMOVEI T2,TCBIR(TCB) ; Received IP options
HLRZ T3,BFROPT(BFR) ; Address for IP options
SKIPE T3 ; If none, don't return any
CALL BLTMU ; IP options to user
MOVX T1,<.RTJST(-1,PTDO)-<MINTHS+3>/4> ; Max TCP option words
XMOVEI T2,TCBTR(TCB) ; Received TCP options
HRRZ T3,BFROPT(BFR) ; Address for TCP options
SKIPE T3 ; If none, don't return any
CALL BLTMU ; TCP options to user
USRBF9: CALL USTTUM ; Unmap the user space & OKSKED
LOAD T1,TPICR,(TCB) ; Get the RECV done PSI Channel
LOAD T2,TPIFR,(TCB) ; And forkx
CALLRET BFRDUN ; Dispose of the buffer
; USRABD(TCB) User ABORT Done
;TCB/ (Extended) Locked Connection Block
;
; CALL USRABD
;Ret+1: Always
USRABD::NOSKED
LOAD T1,TABTFX,(TCB) ; Get FORKX of ABORTer
IFKA < CALL ABTPTR> ; Simulate the ADJBP ...
IFNKA < ADJBP T1,FKABCP> ; Get pointer to that fork's count
LDB T2,T1
SKIPE T2 ; Don't let counter underflow
SUBI T2,1
DPB T2,T1
OKSKED
RET
; BFRDUN(Channel, Forkx, Buffer, TCB) Handle buffer done condition
; Never called for TVTs
;T1/ PSI Channel
;T2/ FORKX to PSI
;BFR/ (Extended) Buffer
;TCB/ (Extended) Locked connection block
;
; CALL BFRDUN
;Ret+1: Always
BFRDUN: NOSKED
CAIE T1,77 ; No channel named?
CAIN T2,-1 ; Or fork went away?
CAIA ; Means no PSI
CALL PSIRQ ; Set off the PSI
LOAD T1,BFRKX,(BFR) ; Fork wherein buffer lives
HLRZ T1,FKPGS(T1) ; Get SPT index of UPT for that fork
CALL DWNSHR ; Decrement share count
JE BIDX,(BFR),BFRDU5 ; Jump if no fork will be waiting
MOVE T1,BFR ; The item to enqueue
MOVE T2,TCPBDQ ; The buffer done queue
CALL NQ ; Pick it up later
LOAD T1,BIDX,(BFR) ; Get the wait bit index
CALL SETWTB ; Make the user wake up now
OKSKED
EXIT BFRDUX
BFRDU5: OKSKED
MOVE T1,BFR ; What to release
CALL RETBLK ; Return the free storage
BUFDUX: RET
; USRINI Initialize the user interface
USRINI::MOVEI T1,QSZ ; Size of a queue head
CALL GETBLK ; Get space from INTSEC
JUMPE T1,USRINX ; No room
MOVEM T1,TCPBDQ ; Save for all to find
CALL INITQ ; Initialize it
SETO T1, ; All ok
USRINX: RET
T